﻿/*
 * Класс для работы с формой обучения сети. Происходит выбор НС, обучение или загрузка НС, составляется обучающая выборка.
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;


namespace DiplomNN
{
    public partial class TrainingForm : Form
    {
        string[] Directories;
        public List<string> Types = new List<string> { "png", "PNG", "jpeg", "JPEG", "bmp", "BMP", "jpg", "JPG" };

        public TrainingForm()
        {
            InitializeComponent();
            SelfRef = this;
        }
        public static TrainingForm SelfRef
        {
            get;
            set;
        }

        public void UpdateTrainingFormPB()
        {
            PBTrainingForm.Image = Helper.ImageFromStartFormScaledBunary;
            PBTrainingForm2.Image = Helper.ImageFromStartFormScaledBunary;           
        }
        public void UpdatePanel()
        {
            AddPictures2(PImages2, TBRootFolderPath2.Text);
        }

        private void TrainingForm_Load(object sender, EventArgs e)
        {
            Helper.IsActiveTrainingForm = true;
        }

        private void TrainingForm_FormClosing(object sender, EventArgs e)
        {
            Helper.IsActiveTrainingForm = false;
        }

        private void tabPage1_Click(object sender, EventArgs e)
        {
            Helper.IsSelectedMP = true;
            Helper.IsSelectedHopfild = false;
        }
        private void tabPage2_Click(object sender, EventArgs e)
        {
            Helper.IsSelectedMP = false;
            Helper.IsSelectedHopfild = true;
        }

        private void BSelectRootFolder_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog FolderDialog = new FolderBrowserDialog();
            if (FolderDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    TBRootFolderPath.Text = FolderDialog.SelectedPath.ToString();
                    if (CBPictureDir.Items.Count > 0)
                    {
                        CBPictureDir.Items.Clear();
                    }
                    string[] files = Directory.GetFiles(TBRootFolderPath.Text);
                    if (files.Length != 0)
                    {
                        for (int i = 0; i < files.Length; i++)
                        {
                            if (GetFileType(files[i]) == "NNMP")
                            {
                                LoadNNToolStripMenuItem.Enabled = true;
                                Helper.LoadPathTrainNN = files[i];
                            }
                        }
                    }
                    Directories = Directory.GetDirectories(TBRootFolderPath.Text);
                    for (int i = 0; i < Directories.Length; i++)
                    {
                        CBPictureDir.Items.Add(Directories[i]);                        
                    }

                    Helper.L3 = Directories.Length;
                    BAddPicture.Enabled = true;
                    BTraining.Enabled = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
            }
        }

        private void CBPictureDir_SelectedIndexChanged(object sender, EventArgs e)
        {
            int count = PImages.Controls.Count;
            for (int i = 0; i < count; i++)
            {
                PImages.Controls[0].Dispose();               
            }
            TBImageName.Text = GetDirektoryName(Directories[CBPictureDir.SelectedIndex]);
            AddPictures(PImages, Directories[CBPictureDir.SelectedIndex]);
            BAddImage.Enabled = true;
            BDelPicture.Enabled = true;
        }

        private void AddPictures(Panel panelImgs, string path)
        {
            string[] files = Directory.GetFiles(path);
            int ImageFileCount = files.Length;
            PictureBox[] PBArr = new PictureBox[files.Length];
            for (int i = 0; i < files.Length; i++)
            {
                int flag = 0;
                foreach (var fi in Types)
                {
                    if (fi.Equals(GetFileType(files[i])))
                    {
                        flag = 1;
                        break;
                    }                    
                }
                if (flag == 1)
                {
                    PBArr[i] = new PictureBox();
                    panelImgs.Controls.Add(PBArr[i]);
                    PBArr[i].Location = new System.Drawing.Point((100 * i) + (2 * (i + 1)), 3);
                    PBArr[i].Size = new System.Drawing.Size(100, 100);
                    PBArr[i].BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
                    PBArr[i].TabIndex = 0;
                    PBArr[i].TabStop = true;
                    PBArr[i].SizeMode = PictureBoxSizeMode.Zoom;
                    PBArr[i].Image = Colors.RgbToBitmap(Colors.BitmapToByteRgb( new Bitmap(files[i])));
                    PBArr[i].Tag = files[i];
                    ContextMenu menu = new ContextMenu();
                    MenuItem Mi = new MenuItem();
                    menu.MenuItems.AddRange (new System.Windows.Forms.MenuItem[] { Mi });
                    Mi.Index = 0;
                    Mi.Text = "Удалить";
                    Mi.Tag = files[i];
                    Mi.Click +=new EventHandler(My_Click);
                    PBArr[i].ContextMenu = menu;
                }
                else
                {
                    ImageFileCount--;
                }
            }
            TBImageCount.Text = ImageFileCount.ToString();
        }

        private void My_Click(object sender, EventArgs e)
        {
            MenuItem PB = sender as MenuItem;
            File.Delete(PB.Tag.ToString());
            CBPictureDir_SelectedIndexChanged(this, null);
        }
        
        public static string GetFileType(String path)
        {
            char separator = '.';
            string[] divided = path.Split(separator);
            return divided[divided.Length - 1];
        }

        public static string GetDirektoryName(String path)
        {
            char separator = '\\';
            string[] divided = path.Split(separator);            
            return divided[divided.Length - 1];
        }

        public static string GetFileName(String path)
        {
            char separator = '\\';
            string[] divided = path.Split(separator);
            separator = '.';
            string[] divided2 = divided[divided.Length - 1].Split(separator);
            return divided2[0];
        }

        private void BAddPicture_Click(object sender, EventArgs e)
        {
            AddNewPictureForm ANPFr = new AddNewPictureForm();
            ANPFr.Show();
        }

        public void AddNewPicture(string namePicture)
        {
            Directory.CreateDirectory(TBRootFolderPath.Text + "\\" + namePicture);
            if (CBPictureDir.Items.Count > 0)
            {
                CBPictureDir.Items.Clear();
            }
            Directories = Directory.GetDirectories(TBRootFolderPath.Text);
            for (int i = 0; i < Directories.Length; i++)
            {
                CBPictureDir.Items.Add(Directories[i]);
                if (GetDirektoryName(Directories[i]).Equals(namePicture))
                {
                    CBPictureDir.SelectedIndex = i;
                }
            }            
            AddPictures(PImages, Directories[CBPictureDir.SelectedIndex]);
        }

        private void BAddImage_Click(object sender, EventArgs e)
        {
            string[] files = Directory.GetFiles(Directories[CBPictureDir.SelectedIndex]);

            for (int i = 0; i < files.Length; i++)
            {
                int ind = files[i].LastIndexOf('\\');
                int j = i + 1;
                File.Move(files[i], files[i].Remove(ind + 1) + j + ".jpeg");
            }

            string[] files1 = Directory.GetFiles(Directories[CBPictureDir.SelectedIndex]);
            for (int i = 0; i < files1.Length; i++)
            {
                int ind = files1[i].LastIndexOf('\\');
                int j = i + 2;
                File.Move(files1[i], files1[i].Remove(ind + 1) + "Img" + j + ".jpeg");
            }

            string filename = Directories[CBPictureDir.SelectedIndex] + "\\Img" + "z.jpeg";
            FileStream fstream = new FileStream(filename, FileMode.Create);
            PBTrainingForm.Image.Save(fstream, System.Drawing.Imaging.ImageFormat.Jpeg);
            fstream.Close();

            files1 = Directory.GetFiles(Directories[CBPictureDir.SelectedIndex]);
            int ind2 = files1[files1.Length - 1].LastIndexOf('\\');
            File.Move(files1[files1.Length - 1], files1[files1.Length - 1].Remove(ind2 + 1) + "Img1.jpeg");
            CBPictureDir_SelectedIndexChanged(this, null);   
        }

        private void BDelPicture_Click(object sender, EventArgs e)
        {
            var result = MessageBox.Show("Вы действительно хочете удалить образ " + TBImageName.Text, "Удаление", MessageBoxButtons.YesNo);
            if (result == System.Windows.Forms.DialogResult.Yes)
            {
                int ind = CBPictureDir.SelectedIndex;
                CBPictureDir.SelectedIndex = 0;
                Directory.Delete(Directories[ind],recursive: true);
                if (CBPictureDir.Items.Count > 0)
                {
                    CBPictureDir.Items.Clear();
                }
                Directories = Directory.GetDirectories(TBRootFolderPath.Text);
                for (int i = 0; i < Directories.Length; i++)
                {
                    CBPictureDir.Items.Add(Directories[i]);
                }
                
            }

        }

        private void BTraining_Click(object sender, EventArgs e)
        {
            Helper.Directories = new string[Directories.Length];
            for (int i = 0; i < Directories.Length; i++)
            {
                Helper.Directories[i] = Directories[i];
            }
            Training.Train();
            MessageBox.Show("Обучение Завершено", "!!!", MessageBoxButtons.OK);
            SaveNNToolStripMenuItem1.Enabled = true;
        }

        private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void SaveNNToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (Helper.IsSelectedMP)
            {
                string[] lines = new string[Helper.Wij.GetLength(0) + Helper.Wjk.GetLength(0) + 2];
                for (int i = 0; i < lines.Length; i++)
                {
                    lines[i] = "";
                    if (i < Helper.Wij.GetLength(0))
                    {
                        for (int j = 0; j < Helper.Wij.GetLength(1); j++)
                        {
                            lines[i] += Helper.Wij[i, j].ToString("0.000000", System.Globalization.CultureInfo.CreateSpecificCulture("da-DK")) + " ";
                        }
                    }
                    else if (i < Helper.Wij.GetLength(0) + Helper.Wjk.GetLength(0))
                    {
                        for (int j = 0; j < Helper.Wjk.GetLength(1); j++)
                        {
                            lines[i] += Helper.Wjk[i - Helper.Wij.GetLength(0), j].ToString("0.000000", System.Globalization.CultureInfo.CreateSpecificCulture("da-DK")) + " ";
                        }
                    }
                    else if (i < Helper.Wij.GetLength(0) + Helper.Wjk.GetLength(0) + 1)
                    {
                        for (int j = 0; j < Helper.Tj.GetLength(0); j++)
                        {
                            lines[i] += Helper.Tj[j].ToString("0.000000", System.Globalization.CultureInfo.CreateSpecificCulture("da-DK")) + " ";
                        }
                    }
                    else
                    {
                        for (int j = 0; j < Helper.Tk.GetLength(0); j++)
                        {
                            lines[i] += Helper.Tk[j].ToString("0.000000", System.Globalization.CultureInfo.CreateSpecificCulture("da-DK")) + " ";
                        }
                    }
                }

                File.WriteAllLines(TBRootFolderPath.Text + "\\SaveNN.NNMP", lines);
            }
            if (Helper.IsSelectedHopfild)
            {
                string[] lines = new string[Helper.GlobalArrayNN.GetLength(0)];
                for (int i = 0; i < Helper.GlobalArrayNN.GetLength(0); i++)
                {
                    lines[i] = "";
                    for (int j = 0; j < Helper.GlobalArrayNN.GetLength(1); j++)
                    {
                        lines[i] += Helper.GlobalArrayNN[i, j].ToString() + " ";
                    }
                }
                File.WriteAllLines(Helper.HopfildDirPath + "\\SaveNN.NNHP", lines);
            }
        }

        private void LoadNNToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (Helper.IsSelectedMP)
            {
                String[] lines = File.ReadAllLines(Helper.LoadPathTrainNN);
                string[] div = lines[lines.Length - 1].Split(' ');
                Helper.L3 = div.Length - 1;
                Helper.Wij = new double[2500, 200];
                Helper.Wjk = new double[200, Helper.L3];
                Helper.Tj = new double[200];
                Helper.Tk = new double[Helper.L3];
                for (int j = 0; j < lines.Length; j++)
                {
                    if (j < 2500)
                    {
                        string[] divided = lines[j].Split(' ');
                        for (int i = 0; i < divided.Length - 1; i++)
                        {
                            Helper.Wij[j, i] = Convert.ToDouble(divided[i]);
                        }
                    }
                    else if (j < 2700)
                    {
                        string[] divided = lines[j].Split(' ');
                        for (int i = 0; i < divided.Length - 1; i++)
                        {
                            Helper.Wjk[j - Helper.Wij.GetLength(0), i] = Convert.ToDouble(divided[i]);
                        }
                    }
                    else if (j < Helper.Wij.GetLength(0) + Helper.Wjk.GetLength(0) + 1)
                    {
                        string[] divided = lines[j].Split(' ');
                        for (int i = 0; i < divided.Length - 1; i++)
                        {
                            Helper.Tj[i] = Convert.ToDouble(divided[i]);
                        }
                    }
                    else
                    {
                        string[] divided = lines[j].Split(' ');
                        for (int i = 0; i < divided.Length - 1; i++)
                        {
                            Helper.Tk[i] = Convert.ToDouble(divided[i]);
                        }
                    }
                }
                Helper.IsTrainedNNMP = true;
                Helper.IsTrainedNNHopfild = false;
                Helper.ArrPict = new TrainPicture[Directories.Length];
                for (int i = 0; i < Directories.Length; i++)
                {
                    string[] files = Directory.GetFiles(Directories[i]);
                    char separator = '\\';
                    string[] divided = Directories[i].Split(separator);
                    Helper.ArrPict[i] = new TrainPicture(divided[divided.Length - 1], files.Length);
                }
                MessageBox.Show("Сеть обучена!", "!!!", MessageBoxButtons.OK);
            }
            if (Helper.IsSelectedHopfild)
            {
                String[] lines = File.ReadAllLines(Helper.HopfildDirPath + "\\SaveNN.NNHP");
                for (int j = 0; j < lines.Length; j++)
                {
                    string[] divided = lines[j].Split(' ');
                    for (int i = 0; i < divided.Length - 1; i++)
                    {
                        Helper.GlobalArrayNN[j, i] = Convert.ToInt32(divided[i]);
                    }
                }
                Helper.IsTrainedNNMP = false;
                Helper.IsTrainedNNHopfild = true;

                string[] files = Directory.GetFiles(Helper.HopfildDirPath);
                int ImageFileCount = files.Length;
                for (int i = 0; i < files.Length; i++)
                {
                    if (TrainingForm.GetFileType(files[i]) == "NNHP")
                    {
                        ImageFileCount--;
                    }
                }
                if (ImageFileCount > 1)
                {
                    Helper.ArrPict = new TrainPicture[ImageFileCount];
                    int l = 0;
                    for (int i = 0; i < files.Length; i++)
                    {
                        if (TrainingForm.GetFileType(files[i]) != "NNHP")
                        {
                            Helper.ArrPict[l] = new TrainPicture(TrainingForm.GetFileName(files[i]), 1);
                            Bitmap Bm = new Bitmap(files[i]);
                            double[] Pic = BodyRecogn.ByteRGBToBynaryArr(Colors.BitmapToByteRgb(Bm));
                            for (int k = 0; k < Pic.Length; k++)
                            {
                                Helper.ArrPict[l].Arr[0, k] = Pic[k];
                                if (Pic[k] == 1)
                                {
                                    Helper.ArrPict[l].ArrPolar[k] = 1;
                                }
                                else
                                {
                                    Helper.ArrPict[l].ArrPolar[k] = -1;
                                }
                            }
                            l++;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
            }
        }

        private void BSelectRootFolder2_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog FolderDialog = new FolderBrowserDialog();
            if (FolderDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    TBRootFolderPath2.Text = FolderDialog.SelectedPath.ToString();
                    Helper.HopfildDirPath = TBRootFolderPath2.Text;
                    string[] files = Directory.GetFiles(TBRootFolderPath2.Text);
                    if (files.Length != 0)
                    {
                        for (int i = 0; i < files.Length; i++)
                        {
                            if (GetFileType(files[i]) == "NNHP")
                            {
                                LoadNNToolStripMenuItem.Enabled = true;
                                Helper.LoadPathTrainNN = files[i];
                            }
                        }
                    }
                    int count = PImages2.Controls.Count;
                    for (int i = 0; i < count; i++)
                    {
                        PImages2.Controls[0].Dispose();
                    }
                    AddPictures2(PImages2, TBRootFolderPath2.Text);

                    BAddPictureHopfild.Enabled = true;
                    BTrainPicture.Enabled = true;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: " + ex.Message);
                }
            }
        }

        public void AddPictures2(Panel panelImgs, string path)
        {
            string[] files = Directory.GetFiles(path);
            int ImageFileCount = files.Length;
            for (int i = 0; i < files.Length; i++)
            {
                if (GetFileType(files[i]) == "NNHP")
                {
                    ImageFileCount--;
                }
            }
            PictureBox[] PBArr = new PictureBox[files.Length];
            TextBox[] TBArr = new TextBox[files.Length];
            int j = 0;
            for (int i = 0; i < files.Length; i++)
            {
                int flag = 0;
                foreach (var fi in Types)
                {
                    if (fi.Equals(GetFileType(files[i])))
                    {
                        flag = 1;
                        break;
                    }
                }
                if (flag == 1)
                {
                    PBArr[i] = new PictureBox();
                    TBArr[i] = new TextBox();
                    panelImgs.Controls.Add(PBArr[i]);
                    panelImgs.Controls.Add(TBArr[i]);
                    PBArr[i].Location = new System.Drawing.Point((100 * (i + j)) + (2 * ((i + j)+ 1)), 3);
                    PBArr[i].Size = new System.Drawing.Size(100, 100);
                    PBArr[i].BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
                    PBArr[i].TabIndex = 0;
                    PBArr[i].TabStop = true;
                    PBArr[i].SizeMode = PictureBoxSizeMode.Zoom;
                    PBArr[i].Image = Colors.RgbToBitmap(Colors.BitmapToByteRgb(new Bitmap(files[i])));
                    PBArr[i].Tag = files[i];
                    ContextMenu menu = new ContextMenu();
                    MenuItem Mi = new MenuItem();
                    menu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { Mi });
                    Mi.Index = 0;
                    Mi.Text = "Удалить";
                    Mi.Tag = files[i];
                    Mi.Click += new EventHandler(My_Click2);
                    PBArr[i].ContextMenu = menu;
                    TBArr[i].Location = new System.Drawing.Point((100 * (i + j)) + (2 * ((i + j) + 1)), 103);
                    TBArr[i].Size = new System.Drawing.Size(100, 10);
                    TBArr[i].Text = GetFileName(files[i]);
                }
                else 
                {
                    j--;
                }
            }            
        }

        private void My_Click2(object sender, EventArgs e)
        {
            MenuItem Mi = sender as MenuItem;
            File.Delete(Mi.Tag.ToString());
            int count = PImages2.Controls.Count;
            for (int i = 0; i < count; i++)
            {
                PImages2.Controls[0].Dispose();
            }
            AddPictures2(PImages2, TBRootFolderPath2.Text);
        }

        private void BAddPictureHopfild_Click(object sender, EventArgs e)
        {
            string[] files = Directory.GetFiles(TBRootFolderPath2.Text);
            if (files.Length < 6)
            {
                int count = PImages2.Controls.Count;
                for (int i = 0; i < count; i++)
                {
                    PImages2.Controls[0].Dispose();
                }
                Helper.SaveImage = PBTrainingForm2.Image;
                AddNewImageForm ANIFr = new AddNewImageForm();
                ANIFr.Show();               
            }                           
            else
            {
                MessageBox.Show("Максимальное число образов равно 5\n Удалите ненужный образ перед добавлением нового", "Внимание", MessageBoxButtons.OK);
            }
        }

        private void BTrainPicture_Click(object sender, EventArgs e)
        {
            Training.TrainHopfild();
            MessageBox.Show("Обучение Завершено", "!!!", MessageBoxButtons.OK);
            SaveNNToolStripMenuItem1.Enabled = true;
        }
              
          

    }
}
